﻿using DoNet.ThirdParty.MiniProfiler;
using DoNet.ThirdParty.UAParser;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using SqlSugar.Extensions;
using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace DoNet.Extensions.ServiceExtensions
{
    /// <summary>
    /// 请求拦截操作
    /// </summary>
    public class RequestActionFilter : IAsyncActionFilter
    {
        private readonly IMediator _mediator;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mediator"></param>
        public RequestActionFilter(IMediator mediator)
        {
            _mediator = mediator;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var sw = new Stopwatch();
            var profiler = MiniProfilerSetup.GetMiniProfiler("StartNew");
            if (profiler != null)
            {
                sw.Start();
                var actionContext = await next();
                sw.Stop();
                profiler.Stop();

                HttpContext httpContext = context.HttpContext;
                var httpRequest = httpContext.Request;
                var isRequestSucceed = actionContext.Exception == null; // 判断是否请求成功（没有异常就是成功）
                var headers = httpRequest.Headers;
                var clientInfo = headers.ContainsKey("User-Agent") ? UAParserSetup.GetClientInfo(headers["User-Agent"].ObjToString()) : null;
                var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                var ip = httpContext.GetClientUserIp();
                var option = new JsonSerializerOptions()
                {
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                };

                #region 生成访问记录
                //VisitLog visitLog = new VisitLog()
                //{
                //    Date = DateTime.Now.AddMilliseconds(-sw.ElapsedMilliseconds),
                //    Account = Appsettings.UserClaims?.FindFirstValue(YuebonClaimConst.UserName),
                //    RealName = Appsettings.UserClaims?.FindFirstValue(YuebonClaimConst.RealName),
                //    IPAddress = ip,
                //    RequestUrl = httpRequest.Path,
                //    OS = clientInfo.OS.Family + clientInfo.OS.Major,
                //    Browser = clientInfo.UA.Family + clientInfo.UA.Major,
                //    ModuleName = context.Controller.ToString(),
                //    MethodName = actionDescriptor?.ActionName,
                //    RequestMethod = httpRequest.Method,
                //    ElapsedTime = sw.ElapsedMilliseconds,
                //    RequestParameter = context.ActionArguments.Count < 1 ? string.Empty : JsonSerializer.Serialize(context.ActionArguments, option),
                //    Result = isRequestSucceed,
                //    Description = JsonSerializer.Serialize(actionContext.Result, option),
                //    Id = IdGeneratorHelper.IdSnowflake()
                //};
                //VisitLogCommand visitLogCommand = new VisitLogCommand()
                //{
                //    VisitLogInput = visitLog
                //};
                //await _mediator.Send(visitLogCommand);
                #endregion  生成访问记录

                #region 记录执行的sql语句
                var sqlList = MiniProfilerSetup.GetSqlList(profiler);
                if (sqlList.Count > 0)
                {
                    WriteLog(sqlList);
                }
                #endregion 记录执行的sql语句
            }
        }

        /// <summary>
        /// sql跟踪
        /// 下载：MiniProfiler.AspNetCore
        /// </summary>
        /// <param name="profiler"></param>
        private void WriteLog(List<SqlLogEntity> list)
        {
            #region 生成执行的sql 记录
            //List<SqlLog> logList = new List<SqlLog>();
            //foreach (var item in list)
            //{
            //    logList.Add(new SqlLog()
            //    {
            //        CreatorTime = DateTime.Now,
            //        Account = "",
            //        Result = item.Errored ? false : true,
            //        ElapsedTime = item.DurationMilliseconds,
            //        Description = $"【{item.CustomTimingKey}{item.CustomTimingIndex}】{item.CommandString}",
            //    });
            //}

            //SqlLogCommand sqlLogCommand = new SqlLogCommand()
            //{
            //    SqlLogInputs = logList
            //};
            //_mediator.Send(sqlLogCommand);
            #endregion 生成执行的sql 记录
        }
    }
}
